package org.slusk.thynwor.util;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;

public class CrossRunAverages {
	public float[] crga_fitness;
	public float[] crga_foodCollected;
	public float[] crga_attachedToFood;
	public float[] crga_assistWithFood;
	public float[] crga_moveTowardSignal;
	public float[] crga_moveFoodTowardGoal;
	public float[] crga_handsFull;
	public float[] crga_hitObstacle;
	public float[] crga_droppedFood;
	public float[] crga_improvementFactor;
	public float[] crga_improvement1Over0;
	public float[] crga_improvement2Over1;
	public float[] crga_improvement2Over0;
	public int numRuns;
	public int popSize;
	
	public CrossRunAverages(int numRuns, int numGens, int popSize) {
		this.numRuns = numRuns;
		this.popSize = popSize;
		crga_fitness = new float[numGens];
		crga_foodCollected = new float[numGens];
		crga_attachedToFood = new float[numGens];
		crga_assistWithFood = new float[numGens];
		crga_moveTowardSignal = new float[numGens];
		crga_moveFoodTowardGoal = new float[numGens];
		crga_handsFull = new float[numGens];
		crga_hitObstacle = new float[numGens];
		crga_droppedFood = new float[numGens];
		crga_improvementFactor = new float[numGens];
		crga_improvement1Over0 = new float[numGens];
		crga_improvement2Over1 = new float[numGens];
		crga_improvement2Over0 = new float[numGens];
	}
	
	public void update(
			float[] fitness
			,float[] foodCollected
			,float[] attachedToFood
			,float[] assistWithFood
			,float[] moveTowardSignal
			,float[] moveFoodTowardGoal
			,float[] handsFull
			,float[] hitObstacle
			,float[] droppedFood
			,float[] improvementFactor
			,float[] improvement1Over0
			,float[] improvement2Over1
			,float[] improvement2Over0	
		) {
		
		for (int gen = 0; gen < crga_fitness.length; gen++) {
			crga_fitness[gen] += crga(fitness, gen);
			crga_foodCollected[gen] += crga(foodCollected, gen);
			crga_attachedToFood[gen] += crga(attachedToFood, gen);
			crga_assistWithFood[gen] += crga(assistWithFood, gen);
			crga_moveTowardSignal[gen] += crga(moveTowardSignal, gen);
			crga_moveFoodTowardGoal[gen] += crga(moveFoodTowardGoal, gen);
			crga_handsFull[gen] += crga(handsFull, gen);
			crga_hitObstacle[gen] += crga(hitObstacle, gen);
			crga_droppedFood[gen] += crga(droppedFood, gen);
			crga_improvementFactor[gen] += crga(improvementFactor, gen);
			crga_improvement1Over0[gen] += crga(improvement1Over0, gen);
			crga_improvement2Over1[gen] += crga(improvement2Over1, gen);
			crga_improvement2Over0[gen] += crga(improvement2Over0, gen);
		}		
		
	}
	
	public void average() {
		for (int gen = 0; gen < crga_fitness.length; gen++) {
			crga_fitness[gen] /= numRuns;
			crga_foodCollected[gen] /= numRuns;
			crga_attachedToFood[gen] /= numRuns;
			crga_assistWithFood[gen] /= numRuns;
			crga_moveTowardSignal[gen] /= numRuns;
			crga_moveFoodTowardGoal[gen] /= numRuns;
			crga_handsFull[gen] /= numRuns;
			crga_hitObstacle[gen] /= numRuns;
			crga_droppedFood[gen] /= numRuns;
			crga_improvementFactor[gen] /= numRuns;
			crga_improvement1Over0[gen] /= numRuns;
			crga_improvement2Over1[gen] /= numRuns;
			crga_improvement2Over0[gen] /= numRuns;
		}
	}
	
	public float crga(float[] a, int generation) {
		float result = 0;
		int start = generation*popSize;
		for (int i = start; i < start + popSize; i++) {
			result += a[i];
		}	
		
		return result/popSize;
	}
	
	public void writeCrossRunGenerationalAveragesToFile(String runName) {
		BufferedWriter bw = null;
		String filepath = "./runs/"+runName+"/crga.csv";
		try {
			bw = new BufferedWriter(new FileWriter(filepath));
			bw.write("Generation"
				+ ",Fitness" +
				",FoodCollected" +
				",AttachedToFood" +
				",AssistWithFood" +
				",MoveTowardsSignal" +
				",MoveTowardGoal" +
				",HandsFull" +
				",HitObstacle" +
				",DroppedFood" +
				",ImprovementFactor" +
				",ImprovementFactor1Over0" +
				",ImprovementFactor2Over1" +
				",ImprovementFactor2Over0" +
				"\n"
			);
			
			for (int i = 0; i < crga_fitness.length; i++) {
				bw.write(i 
						+ ","
						+ crga_fitness[i] + ","
						+ crga_foodCollected[i] + ","
						+ crga_attachedToFood[i] + ","
						+ crga_assistWithFood[i] + ","
						+ crga_moveTowardSignal[i] + ","
						+ crga_moveFoodTowardGoal[i] + ","
						+ crga_handsFull[i] + ","
						+ crga_hitObstacle[i] + ","
						+ crga_droppedFood[i] + ","
						+ crga_improvementFactor[i] + ","
						+ crga_improvement1Over0[i] + ","
						+ crga_improvement2Over1[i] + ","
						+ crga_improvement2Over0[i] + "\n"
				);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != bw)
				try {
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}	
	}
	
}